home *** CD-ROM | disk | FTP | other *** search
- /*
- * Create the main window and everything in it.
- *
- * create_mainwindow(toplvl) Create all widgets in main window
- * print_info_line() print database status into main window
- * remake_dbase_pulldown() put known forms into dbase pulldown
- * remake_section_pulldown() put known sections into sect pulldown
- * remake_query_pulldown() put predefined queries into pulldown
- * remake_sort_pulldown() put sort criteria into sort pulldown
- * switch_form(formname) switch mainwindow to new form
- * search_cards(card,string) do a query for an expression or string
- */
-
- #include "config.h"
- #include <X11/Xos.h>
- #include <stdlib.h>
- #ifdef DIRECT
- #include <sys/dir.h>
- #define dirent direct
- #else
- #include <dirent.h>
- #endif
- #include <Xm/Xm.h>
- #include <Xm/MainW.h>
- #include <Xm/Separator.h>
- #include <Xm/RowColumn.h>
- #include <Xm/Form.h>
- #include <Xm/Frame.h>
- #include <Xm/LabelP.h>
- #include <Xm/ArrowBP.h>
- #include <Xm/ArrowBG.h>
- #include <Xm/Text.h>
- #include <Xm/PushBP.h>
- #include <Xm/PushBG.h>
- #include <X11/cursorfont.h>
- #include "grok.h"
- #include "form.h"
- #include "proto.h"
-
- #define OFF 16 /* margin around summary and card */
- #define NHIST 20 /* remember this many search strings */
-
- #ifndef LIB
- #define LIB "/usr/local/lib"
- #endif
-
- static int append_to_dbase_pulldown(long, char *);
- static void append_search_string(char *);
- static void file_pulldown (Widget, int, XmToggleButtonCallbackStruct *);
- static void newform_pulldown (Widget, int, XmToggleButtonCallbackStruct *);
- static void help_pulldown (Widget, int, XmToggleButtonCallbackStruct *);
- static void dbase_pulldown (Widget, int, XmToggleButtonCallbackStruct *);
- static void section_pulldown (Widget, int, XmToggleButtonCallbackStruct *);
- static void sect_callback (Widget, int, XmToggleButtonCallbackStruct *);
- static void query_pulldown (Widget, int, XmToggleButtonCallbackStruct *);
- static void sort_pulldown (Widget, int, XmToggleButtonCallbackStruct *);
- static void search_callback (Widget, int, XmToggleButtonCallbackStruct *);
- static void letter_callback (Widget, int, XmToggleButtonCallbackStruct *);
- static void pos_callback (Widget, int, XmToggleButtonCallbackStruct *);
- static void new_callback (Widget, XtPointer, XmToggleButtonCallbackStruct *);
- static void dup_callback (Widget, XtPointer, XmToggleButtonCallbackStruct *);
- static void del_callback (Widget, XtPointer, XmToggleButtonCallbackStruct *);
-
- extern Display *display; /* everybody uses the same server */
- extern GC gc; /* everybody uses this context */
- extern struct config config; /* global configuration data */
- extern Pixel color[NCOLS]; /* colors: COL_* */
- extern Pixmap pixmap[NPICS]; /* common symbols */
- extern XmFontList fontlist[NFONTS];
- extern struct pref pref; /* global preferences */
- extern BOOL restricted; /* restricted mode, no form editor */
- extern int col_sorted_by; /* dbase is sorted by this column */
- extern int errno;
- CARD *curr_card; /* card being displayed in main win, */
- char *prev_form; /* previous form name */
- Widget mainwindow; /* popup menus hang off main window */
- static Dimension win_xs, win_ys; /* size of main window w/o sum+card */
- static Widget toplevel; /* need to save this for icon name */
- static Widget menubar; /* menu bar in main window */
- static Widget dbpulldown; /* dbase pulldown menu widget */
- static Widget sectpulldown; /* sectn pulldown menu widget */
- static Widget sortpulldown; /* sort pulldown menu widget */
- static Widget qpulldown; /* query pulldown menu widget */
- static Widget sectpdcall; /* button that calls section pulldn */
-
- static Widget form; /* w_sect etc are on this form */
- static Widget w_info; /* info label, for "n found" */
- static Widget w_search; /* search string text widget */
- static Widget w_prev; /* search prev arrow */
- static Widget w_next; /* search next arrow */
- Widget w_summary; /* form for summary table */
- static Widget w_letter[28]; /* buttons for a,b,c,...,z,misc,* */
- static Widget w_card; /* form for card */
- static Widget w_left; /* button: previous card */
- static Widget w_right; /* button: next card */
- static Widget w_new; /* button: start a new card */
- static Widget w_dup; /* button: duplicate a card */
- static Widget w_del; /* button: delete current card */
- static Widget w_sect; /* button: section popup for card */
-
-
-
- /*
- * create the main window with a menu bar and empty forms for the summary
- * and the card. The forms will be filled later. This routine is called
- * once during startup, before the first switch_form().
- */
-
- void create_mainwindow(
- Widget toplvl)
- {
- XmString s[12];
- Widget fmenu, w, searchform;
- Arg args[15];
- long n, i, wid;
- char buf[10];
-
- toplevel = toplvl;
- mainwindow = XtCreateManagedWidget("mainwindow",
- xmMainWindowWidgetClass, toplevel, NULL, 0);
-
- /*-- menu bar --*/
- s[0] = XmStringCreateSimple("File");
- s[1] = XmStringCreateSimple("Database");
- s[2] = XmStringCreateSimple("Section");
- s[3] = XmStringCreateSimple("Sort");
- s[4] = XmStringCreateSimple("Query");
- s[5] = XmStringCreateSimple("Help");
- menubar = XmVaCreateSimpleMenuBar(mainwindow, "menubar",
- FIX_MENUBAR
- XmVaCASCADEBUTTON, s[0], 'F',
- XmVaCASCADEBUTTON, s[1], 'D',
- XmVaCASCADEBUTTON, s[2], 'e',
- XmVaCASCADEBUTTON, s[3], 'S',
- XmVaCASCADEBUTTON, s[4], 'Q',
- XmVaCASCADEBUTTON, s[5], 'H',
- NULL);
- if (w = XtNameToWidget(menubar, "button_5"))
- XtVaSetValues(menubar, XmNmenuHelpWidget, w, 0);
- sectpdcall = XtNameToWidget(menubar, "button_2");
- for (n=0; n < 5; n++)
- XmStringFree(s[n]);
-
- s[0] = XmStringCreateSimple("Print...");
- s[1] = XmStringCreateSimple("Preferences...");
- s[2] = XmStringCreateSimple("Form editor");
- s[3] = XmStringCreateSimple("About...");
- s[4] = XmStringCreateSimple("Save");
- s[5] = XmStringCreateSimple("Quit");
- s[6] = XmStringCreateSimple("Rambo Quit");
- s[7] = XmStringCreateSimple("Ctrl-P");
- s[8] = XmStringCreateSimple("Ctrl-R");
- s[9] = XmStringCreateSimple("Ctrl-S");
- s[10]= XmStringCreateSimple("Ctrl-Q");
- fmenu = XmVaCreateSimplePulldownMenu(menubar, "file", 0,
- (XtCallbackProc)file_pulldown,
- FIX_MENUBAR
- XmVaPUSHBUTTON, s[0], 'P', "Ctrl<Key>P", s[7],
- XmVaPUSHBUTTON, s[1], 'r', "Ctrl<Key>R", s[8],
- XmVaCASCADEBUTTON, s[2], 'F',
- XmVaPUSHBUTTON, s[3], 'A', NULL, NULL,
- XmVaPUSHBUTTON, s[4], 'S', "Ctrl<Key>S", s[9],
- XmVaPUSHBUTTON, s[5], 'Q', "Ctrl<Key>Q", s[10],
- XmVaPUSHBUTTON, s[6], NULL, NULL, NULL,
- NULL);
- #ifdef XmNtearOffModel
- XtVaSetValues(fmenu, XmNtearOffModel, XmTEAR_OFF_ENABLED, NULL);
- #endif
- XtAddCallback(fmenu, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"pd_file");
- for (n=0; n < 11; n++)
- XmStringFree(s[n]);
-
- if (restricted && (w = XtNameToWidget(fmenu, "button_2")))
- XtVaSetValues(w, XmNsensitive, FALSE, 0);
-
- s[0] = XmStringCreateSimple("Edit current form...");
- s[1] = XmStringCreateSimple("Create new form from scratch...");
- s[2] = XmStringCreateSimple("Create, use current as template...");
- fmenu = XmVaCreateSimplePulldownMenu(fmenu, "newform", 2,
- (XtCallbackProc)newform_pulldown,
- FIX_MENUBAR
- XmVaPUSHBUTTON, s[0], 'E', NULL, NULL,
- XmVaPUSHBUTTON, s[1], 'C', NULL, NULL,
- XmVaPUSHBUTTON, s[2], 't', NULL, NULL,
- NULL);
- #ifdef XmNtearOffModel
- XtVaSetValues(fmenu, XmNtearOffModel, XmTEAR_OFF_ENABLED, NULL);
- #endif
- XtAddCallback(fmenu, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"pd_file");
- for (n=0; n < 3; n++)
- XmStringFree(s[n]);
-
- dbpulldown = XmVaCreateSimplePulldownMenu(menubar, "dbase", 1,
- (XtCallbackProc)dbase_pulldown,
- FIX_MENUBAR
- NULL);
- XtAddCallback(dbpulldown, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"pd_dbase");
-
- sectpulldown = XmVaCreateSimplePulldownMenu(menubar, "section", 2,
- (XtCallbackProc)section_pulldown,
- FIX_MENUBAR
- NULL);
- XtAddCallback(sectpulldown, XmNhelpCallback,
- (XtCallbackProc)help_callback,(XtPointer)"pd_section");
-
- sortpulldown = XmVaCreateSimplePulldownMenu(menubar, "sort", 3,
- (XtCallbackProc)sort_pulldown,
- FIX_MENUBAR
- NULL);
- XtAddCallback(sortpulldown, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"pd_sort");
-
- qpulldown = XmVaCreateSimplePulldownMenu(menubar, "query", 4,
- (XtCallbackProc)query_pulldown,
- FIX_MENUBAR
- NULL);
- XtAddCallback(qpulldown, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"pd_query");
-
- s[0] = XmStringCreateSimple("On context");
- s[1] = XmStringCreateSimple("Current database");
- s[2] = XmStringCreateSimple("Introduction");
- s[3] = XmStringCreateSimple("Getting help");
- s[4] = XmStringCreateSimple("Troubleshooting");
- s[5] = XmStringCreateSimple("Files and programs");
- s[6] = XmStringCreateSimple("Expression grammar");
- s[7] = XmStringCreateSimple("Variables and X Resources");
- s[8] = XmStringCreateSimple("Ctrl-H");
- s[9] = XmStringCreateSimple("Ctrl-D");
- s[10]= XmStringCreateSimple("Ctrl-G");
- fmenu = XmVaCreateSimplePulldownMenu(menubar, "help", 5,
- (XtCallbackProc)help_pulldown,
- FIX_MENUBAR
- XmVaPUSHBUTTON, s[0], 'C', "Ctrl<Key>H", s[8],
- XmVaPUSHBUTTON, s[1], 'D', "Ctrl<Key>D", s[9],
- XM_VA_SEPARATOR
- XmVaPUSHBUTTON, s[2], 'I', NULL, NULL,
- XmVaPUSHBUTTON, s[3], 'G', NULL, NULL,
- XmVaPUSHBUTTON, s[4], 'T', NULL, NULL,
- XmVaPUSHBUTTON, s[5], 'F', NULL, NULL,
- XmVaPUSHBUTTON, s[6], 'E', "Ctrl<Key>G", s[10],
- XmVaPUSHBUTTON, s[7], 'V', NULL, NULL,
- NULL);
- #ifdef XmNtearOffModel
- XtVaSetValues(fmenu, XmNtearOffModel, XmTEAR_OFF_ENABLED, NULL);
- #endif
- for (n=0; n < 10; n++)
- XmStringFree(s[n]);
-
- form = XtCreateWidget("mainform", xmFormWidgetClass,
- mainwindow, NULL, 0);
- /*-- search string --*/
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNtopOffset, 10); n++;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNleftOffset, OFF); n++;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNrightOffset, OFF); n++;
- searchform = XtCreateManagedWidget("searchform", xmFormWidgetClass,
- form, args, n);
- XtAddCallback(searchform, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"search");
-
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- w = XtCreateManagedWidget("Search", xmPushButtonWidgetClass,
- searchform, args, n);
- XtAddCallback(w, XmNactivateCallback,
- (XtCallbackProc)search_callback, (XtPointer)0);
- XtAddCallback(w, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"search");
-
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNtopOffset, 3); n++;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNbottomOffset, 3); n++;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNrightWidget, w); n++;
- XtSetArg(args[n], XmNrightOffset, 10); n++;
- XtSetArg(args[n], XmNarrowDirection, XmARROW_RIGHT); n++;
- XtSetArg(args[n], XmNsensitive, FALSE); n++;
- XtSetArg(args[n], XmNforeground, color[COL_BACK]); n++;
- w = w_next = XtCreateManagedWidget("next", xmArrowButtonWidgetClass,
- searchform, args, n);
- XtAddCallback(w, XmNactivateCallback,
- (XtCallbackProc)search_callback, (XtPointer)1);
- XtAddCallback(w, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"search");
-
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNtopOffset, 3); n++;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNbottomOffset, 3); n++;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNrightWidget, w); n++;
- XtSetArg(args[n], XmNarrowDirection, XmARROW_LEFT); n++;
- XtSetArg(args[n], XmNsensitive, FALSE); n++;
- XtSetArg(args[n], XmNforeground, color[COL_BACK]); n++;
- w = w_prev = XtCreateManagedWidget("prev", xmArrowButtonWidgetClass,
- searchform, args, n);
- XtAddCallback(w, XmNactivateCallback,
- (XtCallbackProc)search_callback, (XtPointer)-1);
- XtAddCallback(w, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"search");
-
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNfontList, fontlist[FONT_HELV]); n++;
- w = XtCreateManagedWidget("Search:", xmLabelWidgetClass,
- searchform, args, n);
-
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNleftWidget, w); n++;
- XtSetArg(args[n], XmNleftOffset, OFF); n++;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNrightWidget, w_prev); n++;
- XtSetArg(args[n], XmNrightOffset, OFF); n++;
- XtSetArg(args[n], XmNpendingDelete, True); n++;
- XtSetArg(args[n], XmNbackground, color[COL_TEXTBACK]); n++;
- XtSetArg(args[n], XmNfontList, fontlist[FONT_HELV]); n++;
- w_search = XtCreateManagedWidget(" ", xmTextWidgetClass,
- searchform, args, n);
- XtAddCallback(w_search, XmNactivateCallback,
- (XtCallbackProc)search_callback, NULL);
- XtAddCallback(w_search, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"search");
-
- /*-- info line --*/
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNtopWidget, searchform); n++;
- XtSetArg(args[n], XmNtopOffset, 10); n++;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNleftOffset, OFF); n++;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNrightOffset, OFF); n++;
- XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
- XtSetArg(args[n], XmNfontList, fontlist[FONT_HELV]); n++;
- w_info = XtCreateManagedWidget(" ", xmLabelWidgetClass,
- form, args, n);
- XtAddCallback(w_info, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"info");
-
- /*-- buttons --*/
- n = 0;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNbottomOffset, 8); n++;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNleftOffset, OFF); n++;
- XtSetArg(args[n], XmNwidth, 30); n++;
- XtSetArg(args[n], XmNheight, 30); n++;
- XtSetArg(args[n], XmNlabelType, XmPIXMAP); n++;
- XtSetArg(args[n], XmNlabelPixmap, pixmap[PIC_LEFT]); n++;
- XtSetArg(args[n], XmNsensitive, False); n++;
- XtSetArg(args[n], XmNhighlightThickness,1); n++;
- w_left = XtCreateManagedWidget("Left", xmPushButtonWidgetClass,
- form, args, n);
- XtAddCallback(w_left, XmNactivateCallback,
- (XtCallbackProc)pos_callback, (XtPointer)-1);
- XtAddCallback(w_left, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"pos");
-
- n = 0;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNbottomOffset, 8); n++;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNleftWidget, w_left); n++;
- XtSetArg(args[n], XmNleftOffset, 4); n++;
- XtSetArg(args[n], XmNwidth, 30); n++;
- XtSetArg(args[n], XmNheight, 30); n++;
- XtSetArg(args[n], XmNlabelType, XmPIXMAP); n++;
- XtSetArg(args[n], XmNlabelPixmap, pixmap[PIC_RIGHT]); n++;
- XtSetArg(args[n], XmNsensitive, False); n++;
- XtSetArg(args[n], XmNhighlightThickness,1); n++;
- w_right = XtCreateManagedWidget("Right", xmPushButtonWidgetClass,
- form, args, n);
- XtAddCallback(w_right, XmNactivateCallback,
- (XtCallbackProc)pos_callback, (XtPointer)1);
- XtAddCallback(w_right, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"pos");
-
- n = 0;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNbottomOffset, 8); n++;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNleftWidget, w_right); n++;
- XtSetArg(args[n], XmNleftOffset, 16); n++;
- XtSetArg(args[n], XmNwidth, 60); n++;
- XtSetArg(args[n], XmNsensitive, False); n++;
- XtSetArg(args[n], XmNhighlightThickness,1); n++;
- w_new = XtCreateManagedWidget("New", xmPushButtonWidgetClass,
- form, args, n);
- XtAddCallback(w_new, XmNactivateCallback,
- (XtCallbackProc)new_callback, (XtPointer)0);
- XtAddCallback(w_new, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"new");
-
- n = 0;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNbottomOffset, 8); n++;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNleftWidget, w_new); n++;
- XtSetArg(args[n], XmNleftOffset, 8); n++;
- XtSetArg(args[n], XmNwidth, 60); n++;
- XtSetArg(args[n], XmNsensitive, False); n++;
- XtSetArg(args[n], XmNhighlightThickness,1); n++;
- w_dup = XtCreateManagedWidget("Dup", xmPushButtonWidgetClass,
- form, args, n);
- XtAddCallback(w_dup, XmNactivateCallback,
- (XtCallbackProc)dup_callback, (XtPointer)0);
- XtAddCallback(w_dup, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"dup");
-
- n = 0;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNbottomOffset, 8); n++;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNleftWidget, w_dup); n++;
- XtSetArg(args[n], XmNleftOffset, 8); n++;
- XtSetArg(args[n], XmNwidth, 60); n++;
- XtSetArg(args[n], XmNsensitive, False); n++;
- XtSetArg(args[n], XmNhighlightThickness,1); n++;
- w_del = XtCreateManagedWidget("Delete", xmPushButtonWidgetClass,
- form, args, n);
- XtAddCallback(w_del, XmNactivateCallback,
- (XtCallbackProc)del_callback, (XtPointer)0);
- XtAddCallback(w_del, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"del");
-
- n = 0;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNbottomOffset, 8); n++;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNrightOffset, OFF); n++;
- XtSetArg(args[n], XmNwidth, 60); n++;
- XtSetArg(args[n], XmNhighlightThickness,1); n++;
- w = XtCreateManagedWidget("Help", xmPushButtonWidgetClass,
- form, args, n);
- XtAddCallback(w, XmNactivateCallback,
- (XtCallbackProc)help_callback, (XtPointer)"card");
- XtAddCallback(w, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"card");
-
- /*-- summary --*/
- n = 0;
- XtSetArg(args[n], XmNwidth, 400); n++;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNtopWidget, w_info); n++;
- XtSetArg(args[n], XmNtopOffset, 4); n++;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNleftOffset, OFF); n++;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNrightOffset, OFF); n++;
- w = w_summary = XtCreateManagedWidget("summform", xmFormWidgetClass,
- form, args, n);
- XtAddCallback(w, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"summary");
-
- /*-- letters --*/
- if (pref.letters) {
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNtopWidget, w_summary); n++;
- XtSetArg(args[n], XmNtopOffset, 5); n++;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNleftOffset, OFF+2); n++;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNrightOffset, OFF); n++;
- w = XtCreateManagedWidget("letters", xmFormWidgetClass,
- form, args, n);
- XtAddCallback(w, XmNhelpCallback,
- (XtCallbackProc)help_callback,(XtPointer)"letters");
-
- for (i=0; i < 28; i++) {
- wid = strlen_in_pixels("W", FONT_STD);
- sprintf(buf, i < 26 ? "%c" : i==26 ? "misc" : "all", i+'A');
- n = 0;
- if (i == 0) {
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- } else {
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNleftWidget, w_letter[i-1]); n++;
- }
- if (i < 26) {
- XtSetArg(args[n], XmNwidth, wid + 6); n++;
- }
- XtSetArg(args[n], XmNheight, wid + 6); n++;
- XtSetArg(args[n], XmNleftOffset, 0); n++;
- XtSetArg(args[n], XmNshadowThickness, 2); n++;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNbottomAttachment,XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNhighlightThickness, 0); n++;
- w_letter[i] = XtCreateManagedWidget(buf, xmPushButtonWidgetClass,
- w, args, n);
- XtAddCallback(w_letter[i], XmNactivateCallback,
- (XtCallbackProc)letter_callback, (XtPointer)i);
- XtAddCallback(w_letter[i], XmNhelpCallback,
- (XtCallbackProc) help_callback, (XtPointer)"letters");
- }
- }
- /*-- card --*/
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNtopWidget, w); n++;
- XtSetArg(args[n], XmNtopOffset, OFF); n++;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- w = XtCreateManagedWidget(" ", xmSeparatorWidgetClass,
- form, args, n);
- n = 0;
- XtSetArg(args[n], XmNwidth, 400); n++;
- XtSetArg(args[n], XmNheight, 6); n++;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNtopWidget, w); n++;
- XtSetArg(args[n], XmNtopOffset, OFF); n++;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNbottomWidget, w_new); n++;
- XtSetArg(args[n], XmNbottomOffset, 8); n++;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNleftOffset, OFF); n++;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNrightOffset, OFF); n++;
- w_card = XtCreateManagedWidget("cardform", xmFormWidgetClass,
- form, args, n);
- XtAddCallback(w_card, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"card");
-
- XtManageChild(form);
- XtManageChild(menubar);
- create_summary_menu(curr_card, w_summary, mainwindow);
- remake_dbase_pulldown();
- remake_section_pulldown();
- remake_query_pulldown();
- remake_sort_pulldown();
- }
-
-
- /*
- * resize the main window such that there is enough room for the summary
- * and the card. During startup, create_mainwindow() has stored the size
- * without summary and card, now add enough space for the new summary and
- * card and resize the window.
- */
-
- void resize_mainwindow(void)
- {
- Arg args[2];
- Dimension xs=0, ys=0;
-
- if (!win_ys) {
- XtSetArg(args[0], XmNwidth, &win_xs);
- XtSetArg(args[1], XmNheight, &win_ys);
- XtGetValues(mainwindow, args, 2);
- win_ys -= 1;
- }
- if (curr_card && curr_card->form) {
- xs = pref.scale * curr_card->form->xs + 2;
- ys = pref.scale * curr_card->form->ys + 2;
- }
- if (win_xs > xs) xs = win_xs;
- XtSetArg(args[0], XmNwidth, xs + 2*2 + 2*16);
- XtSetArg(args[1], XmNheight, win_ys + ys + 2*3);
- XtSetValues(XtParent(mainwindow), args, 2);
- }
-
-
- /*
- * print some enlightening info about the database into the info line between
- * the search string and the summary. This is called whenever something
- * changes: either the database was modified, or saved (modified is turned
- * off), or a search is done.
- */
-
- void print_info_line(void)
- {
- char buf[256];
- register CARD *card = curr_card;
- register DBASE *dbase;
- int s, n;
-
- if (!display)
- return;
- if (!card || !card->dbase || !card->form || !card->form->name)
- strcpy(buf, "No database");
- else {
- dbase = card->dbase;
- s = dbase->nsects > 1 ? dbase->currsect : -1;
- n = s >= 0 ? dbase->sect[s].nrows : dbase->nrows;
- if (!dbase->nrows)
- strcpy(buf, "No cards");
- else
- sprintf(buf, "%s: %d of %d card%s", card->form->name,
- card->nquery, n, n==1 ? "" : "s");
- if (s >= 0) {
- strcat(buf, " in section ");
- strcat(buf, section_name(dbase, s));
- }
- if (s >= 0 ? dbase->sect[s].rdonly : dbase->rdonly)
- strcat(buf, " (read only)");
- if (s >= 0 ? dbase->sect[s].modified : dbase->modified)
- strcat(buf, " (modified)");
- }
- print_button(w_info, buf);
- }
-
-
- /*-------------------------------------------------- variable pulldowns -----*/
- /*
- * Read the current directory, the ./grokdir directory, the GROKDIR directory,
- * and the preference directories, and collect all form files (*.f) and put
- * them into the Form pulldown (pulldown #1). This is, of course, a flagrant
- * violation of the Motif style guide.
- */
-
- #define MAXD 200 /* no more than 200 databases in pulldown */
- static char *dbname[MAXD]; /* callback gets an index into this array */
- static char *dbpath[MAXD]; /* path where form file was found */
- static Widget dbwidget[MAXD]; /* button widgets, destroyed before remake */
-
- static int append_to_dbase_pulldown(
- long nlines, /* # of databases already in pulldown*/
- char *path) /* directory name */
- {
- char *p; /* for removing extension */
- DIR *dir; /* open directory file */
- struct dirent *dp; /* one directory entry */
- int num=0, i;
-
- path = resolve_tilde(path, 0);
- if (!(dir = opendir(path)))
- return(nlines);
- while (nlines < MAXD-!num) {
- if (!(dp = readdir(dir)))
- break;
- if (!(p = strrchr(dp->d_name, '.')) || strcmp(p, ".gf"))
- continue;
- *p = 0;
- for (i=0; i < nlines; i++)
- if (dbpath[i] && (pref.uniquedb ||
- !strcmp(dbpath[i], path))
- && !strcmp(dbname[i], dp->d_name))
- break;
- if (i < nlines)
- continue;
- # ifndef NOMSEP
- if (!num++ && nlines)
- dbwidget[nlines++] = XtCreateManagedWidget(" ",
- xmSeparatorWidgetClass, dbpulldown, NULL, 0);
- # endif
- dbname[nlines] = mystrdup(dp->d_name);
- dbpath[nlines] = mystrdup(path);
- dbwidget[nlines] = XtCreateManagedWidget(dp->d_name,
- xmPushButtonGadgetClass, dbpulldown, NULL, 0);
- XtAddCallback(dbwidget[nlines], XmNactivateCallback,
- (XtCallbackProc)dbase_pulldown, (XtPointer)nlines);
- nlines++;
- }
- (void)closedir(dir);
- return(nlines);
- }
-
-
- void remake_dbase_pulldown(void)
- {
- int n;
- char path[1024], *env;
-
- for (n=0; n < MAXD; n++) {
- if (dbwidget[n])
- XtDestroyWidget(dbwidget[n]);
- if (dbpath[n])
- free((void *)dbpath[n]);
- if (dbname[n])
- free((void *)dbname[n]);
- dbwidget[n] = 0;
- dbname[n] = 0;
- dbpath[n] = 0;
- }
- sprintf(path, "%s/grokdir", LIB);
- env = getenv("GROK_FORM");
- n = append_to_dbase_pulldown(0, env ? env : "./");
- n = append_to_dbase_pulldown(n, "./grokdir");
- n = append_to_dbase_pulldown(n, GROKDIR);
- n = append_to_dbase_pulldown(n, path);
- #ifdef XmNtearOffModel
- XtVaSetValues(dbpulldown, XmNtearOffModel, XmTEAR_OFF_ENABLED, NULL);
- #endif
- }
-
-
- /*
- * After a database was loaded, there is a section list in the dbase struct.
- * Present it in a pulldown if there are at least two sections.
- */
-
- #define MAXSC 200 /* no more than 200 sections in pulldown */
- static Widget scwidget[MAXSC]; /* button widgets, destroyed before remake */
-
- void remake_section_pulldown(void)
- {
- int maxn;
- long n;
-
- for (n=0; n < MAXSC; n++) {
- if (scwidget[n])
- XtDestroyWidget(scwidget[n]);
- scwidget[n] = 0;
- }
- if (!curr_card || !curr_card->dbase || curr_card->form->proc) {
- XtVaSetValues(sectpdcall, XmNsensitive, FALSE, 0);
- return;
- }
- maxn = curr_card->dbase->havesects ? curr_card->dbase->nsects + 2 : 1;
- if (maxn > MAXSC)
- maxn = MAXSC;
- for (n=0; n < maxn; n++) {
- scwidget[n] = XtCreateManagedWidget(
- n == maxn-1 ? "New ..." :
- n == 0 ? "All" :
- section_name(curr_card->dbase, n-1),
- xmPushButtonGadgetClass, sectpulldown, NULL,0);
- XtAddCallback(scwidget[n], XmNactivateCallback,
- (XtCallbackProc)section_pulldown,(XtPointer)n);
- }
- XtVaSetValues(sectpdcall, XmNsensitive, TRUE, 0);
- #ifdef XmNtearOffModel
- XtVaSetValues(sectpulldown, XmNtearOffModel, XmTEAR_OFF_ENABLED, NULL);
- #endif
- remake_section_popup(TRUE);
- }
-
-
- /*
- * Put all the default queries in the form into the Query pulldown (pulldown
- * #3). Add a default query "All" at the top. This is yet another violation
- * of the Motif style guide. So what.
- */
-
- #define MAXQ 100 /* no more than 100 queries in pulldown */
- static Widget qwidget[MAXQ]; /* button widgets, destroyed before remake */
-
- void remake_query_pulldown(void)
- {
- DQUERY *dq; /* current query entry */
- long i; /* # of queries in pulldown */
- int n; /* max # of lines in pulldown */
-
- for (n=0; n < MAXQ; n++) {
- if (qwidget[n])
- XtDestroyWidget(qwidget[n]);
- qwidget[n] = 0;
- }
- if (!curr_card || !curr_card->form)
- return;
-
- qwidget[0] = XtCreateManagedWidget("All",
- xmPushButtonGadgetClass, qpulldown, NULL, 0);
- XtAddCallback(qwidget[0], XmNactivateCallback,
- (XtCallbackProc)query_pulldown, (XtPointer)0);
- n = curr_card->form->nqueries > MAXQ ? MAXQ
- : curr_card->form->nqueries;
- for (i=0; i < n; i++) {
- dq = &curr_card->form->query[i];
- if (dq->suspended || !dq->name || !dq->query)
- continue;
- qwidget[i+1] = XtCreateManagedWidget(dq->name,
- xmPushButtonGadgetClass, qpulldown, NULL, 0);
- XtAddCallback(qwidget[i+1], XmNactivateCallback,
- (XtCallbackProc)query_pulldown,
- (XtPointer)(i+1));
- }
- #ifdef XmNtearOffModel
- XtVaSetValues(qpulldown, XmNtearOffModel, XmTEAR_OFF_ENABLED, NULL);
- #endif
- }
-
-
- /*
- * put a new option popup menu on the card's Section button
- */
-
- static void remake_popup(void);
- static Widget *pwidgets; /* label widgets in popup */
- static int pnwidgets; /* number of widgets in pwidgets[] */
-
- void remake_section_popup(
- BOOL newsects) /* did the section list change? */
- {
- #ifdef XmCSimpleOptionMenu
- Arg args[2];
-
- if (newsects)
- remake_popup();
-
- if (!curr_card || !curr_card->dbase
- || curr_card->row < 0
- || curr_card->row >= curr_card->dbase->nrows
- || !curr_card->dbase->havesects) {
- if (w_sect) {
- XtSetArg(args[0], XmNsensitive, FALSE);
- XtSetValues(w_sect, args, 1);
- XtSetValues(w_del, args, 1);
- XtSetValues(XmOptionButtonGadget(w_sect), args, 1);
- }
- return;
- }
- if (w_sect) {
- XtSetArg(args[0], XmNsensitive, TRUE);
- XtSetArg(args[1], XmNmenuHistory, pwidgets[
- curr_card->dbase->row[curr_card->row]->section]);
- XtSetValues(w_sect, args, 2);
- XtSetValues(w_del, args, 1);
- XtSetValues(XmOptionButtonGadget(w_sect), args, 1);
- }
- #endif
- }
-
-
- static void remake_popup(void)
- {
- #ifdef XmCSimpleOptionMenu
- static Widget popup; /* the popup menu */
- XmString str; /* for labels in pwidgets, temp */
- Arg args[20]; /* for option menu creation */
- int i, n;
-
- if (w_sect) {
- XtDestroyWidget(w_sect);
- w_sect = 0;
- }
- if (popup) {
- XtDestroyWidget(popup);
- popup = 0;
- }
- if (pwidgets) {
- for (i=0; i < pnwidgets; i++)
- XtDestroyWidget(pwidgets[i]);
- free(pwidgets);
- pwidgets = 0;
- }
- pnwidgets = curr_card->dbase->nsects;
- if (pnwidgets < 2) {
- pnwidgets = 0;
- return;
- }
- if (!(pwidgets = malloc(sizeof(Widget) * pnwidgets)))
- return;
-
- popup = XmCreatePulldownMenu(form, "pulldown", NULL, 0);
- str = XmStringCreateSimple("");
- n = 0;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
- XtSetArg(args[n], XmNbottomWidget, w_del); n++;
- XtSetArg(args[n], XmNmarginHeight, 0); n++;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNleftWidget, w_del); n++;
- XtSetArg(args[n], XmNwidth, 60); n++;
- XtSetArg(args[n], XmNhighlightThickness,1); n++;
- XtSetArg(args[n], XmNsubMenuId, popup); n++;
- XtSetArg(args[n], XmNlabelString, str); n++;
- w_sect = XmCreateOptionMenu(form, "sectoption", args, n);
- XtAddCallback(w_sect, XmNhelpCallback,
- (XtCallbackProc)help_callback, (XtPointer)"sect");
- XmStringFree(str);
-
- for (i=0; i < pnwidgets; i++) {
- XtSetArg(args[0], XmNsensitive,
- !curr_card->dbase->sect[i].rdonly);
- pwidgets[i] = XtCreateManagedWidget(
- section_name(curr_card->dbase, i),
- xmPushButtonGadgetClass, popup, NULL, 0);
- XtAddCallback(pwidgets[i], XmNactivateCallback,
- (XtCallbackProc)sect_callback, (XtPointer)i);
- }
- XtManageChild(w_sect);
- #endif
- }
-
-
- /*
- * Put all the columns in the summary into the Sort pulldown (pulldown #2),
- * except those that have the nosort flag set.
- * What you hear weeping is the author of the Motif style guide.
- */
-
- #define MAXS 100 /* no more than 100 criteria in pulldown */
- static Widget swidget[MAXS]; /* button widgets, destroyed before remake */
-
- void remake_sort_pulldown(void)
- {
- int sort_col[MAXS]; /* column for each pulldown item */
- char buf[256]; /* pulldown line text */
- register ITEM *item; /* scan items for sortable columns */
- int i; /* item counter */
- int j; /* skip redundant choice items */
- int n; /* # of lines in pulldown */
-
- for (n=0; n < MAXS; n++) {
- if (swidget[n])
- XtDestroyWidget(swidget[n]);
- swidget[n] = 0;
- }
- if (!curr_card || !curr_card->form || !curr_card->dbase)
- return;
-
- for (n=i=0; i < curr_card->form->nitems; i++) {
- item = curr_card->form->items[i];
- if (!IN_DBASE(item->type) || item->nosort)
- continue;
- for (j=0; j < n; j++)
- if (item->column == sort_col[j])
- break;
- if (j < n)
- continue;
- sprintf(buf, "by %.200s",
- item->type == IT_CHOICE ? item->name : item->label);
- if (buf[j = strlen(buf)-1] == ':')
- buf[j] = 0;
- swidget[n] = XtCreateManagedWidget(buf,
- xmPushButtonGadgetClass, sortpulldown, NULL,0);
- XtAddCallback(swidget[n], XmNactivateCallback,
- (XtCallbackProc)sort_pulldown,
- (XtPointer)item->column);
- sort_col[n++] = item->column;
- }
- #ifdef XmNtearOffModel
- XtVaSetValues(sortpulldown, XmNtearOffModel, XmTEAR_OFF_ENABLED,NULL);
- #endif
- }
-
-
- /*-------------------------------------------------- switch databases -------*/
- /*
- * switch main window to new database. This happens on startup if a form
- * name is given on the command line, and whenever a new form name is chosen
- * from the database pulldown. ".gf" is appended to formname if necessary. If
- * formname == 0, kill the current form and don't switch to a new one. Sort
- * the new database by the default sort criterion if there is one.
- */
-
- void switch_form(
- char *formname) /* new form name */
- {
- char name[1024], *p; /* capitalized formname */
- Arg args[5];
- int i;
-
- if (curr_card) {
- if (prev_form)
- free(prev_form);
- prev_form = 0;
- if (curr_card->form)
- prev_form = mystrdup(curr_card->form->name);
- destroy_card_menu(curr_card);
- if (curr_card->dbase) {
- if (curr_card->dbase->modified &&
- !curr_card->dbase->rdonly &&
- !curr_card->form->rdonly)
- if (!write_dbase(curr_card->dbase,
- curr_card->form, FALSE))
- return;
- dbase_delete(curr_card->dbase);
- free((void *)curr_card->dbase);
- }
- if (curr_card->form) {
- form_delete(curr_card->form);
- free((void *)curr_card->form);
- }
- free((void *)curr_card);
- curr_card = 0;
- }
- if (formname && *formname) {
- FORM *form = form_create();
- DBASE *dbase = dbase_create();
- if (read_form(form, formname))
- (void)read_dbase(dbase, form,
- form->dbase ? form->dbase : formname);
-
- curr_card = create_card_menu(form, dbase, w_card);
- curr_card->form = form;
- curr_card->dbase = dbase;
- curr_card->row = 0;
- col_sorted_by = 0;
- for (i=0; i < form->nitems; i++)
- if (form->items[i]->defsort) {
- dbase_sort(curr_card, form->items[i]->column);
- break;
- }
- if (form->autoquery >= 0 && form->autoquery < form->nqueries)
- query_any(curr_card,
- form->query[form->autoquery].query);
- else
- query_all(curr_card);
- create_summary_menu(curr_card, w_summary, mainwindow);
-
- strcpy(name, formname);
- if (*name >= 'a' && *name <= 'z')
- *name += 'A' - 'a';
- if (p = strrchr(name, '.'))
- *p = 0;
- if (p = strrchr(name, '/'))
- p++;
- else
- p = name;
- if (toplevel) {
- XtVaSetValues(toplevel, XmNiconName, p, NULL);
- fillout_card(curr_card, FALSE);
- }
- } else
- if (toplevel)
- XtVaSetValues(toplevel, XmNiconName, "None", NULL);
-
- if (toplevel) {
- XtSetArg(args[0], XmNsensitive, formname != 0);
- XtSetValues(w_left, args, 1);
- XtSetValues(w_right, args, 1);
- XtSetValues(w_del, args, 1);
- XtSetValues(w_dup, args, 1);
- XtSetValues(w_new, args, 1);
-
- remake_query_pulldown();
- remake_sort_pulldown();
- remake_section_pulldown(); /* also sets w_sect, w_del */
- resize_mainwindow();
- if (curr_card && curr_card->dbase)
- curr_card->dbase->modified = FALSE;
- print_info_line();
- }
- }
-
-
- /*-------------------------------------------------- callbacks --------------*/
- /*
- * some item in one of the menu bar pulldowns was pressed. All of these
- * routines are direct X callbacks.
- */
-
- static void rambo_quit(void) { exit(0); }
-
- /*ARGSUSED*/
- static void file_pulldown(
- Widget widget,
- int item,
- XmToggleButtonCallbackStruct *data)
- {
- card_readback_texts(curr_card, -1);
- switch (item) {
- case 0: /* print */
- create_print_popup();
- break;
-
- case 1: /* preference*/
- create_preference_popup();
- break;
-
- case 3: /* about */
- create_about_popup();
- break;
-
- case 4: /* save */
- if (curr_card && curr_card->form && curr_card->dbase)
- if (curr_card->form->rdonly)
- create_error_popup(mainwindow, 0,
- "Database is marked read-only in the form");
- else
- (void)write_dbase(curr_card->dbase,
- curr_card->form, TRUE);
- else
- create_error_popup(mainwindow,0,"No database to save");
- print_info_line();
- break;
-
- case 5: /* quit */
- if (curr_card && curr_card->dbase
- && curr_card->dbase->modified
- && !curr_card->form->rdonly
- && !write_dbase(curr_card->dbase,
- curr_card->form, FALSE))
- break;
- exit(0);
-
- case 6: /* rambo quit*/
- if (curr_card && curr_card->dbase
- && !curr_card->dbase->rdonly
- && curr_card->dbase->modified
- && !curr_card->form->rdonly)
- create_query_popup(mainwindow, rambo_quit, "rambo",
- "OK to discard changes and quit?");
- else
- exit(0);
- }
- }
-
-
- /*ARGSUSED*/
- static void newform_pulldown(
- Widget widget,
- int item,
- XmToggleButtonCallbackStruct *data)
- {
- card_readback_texts(curr_card, -1);
- switch (item) {
- case 0: /* current */
- if (curr_card && curr_card->form) {
- if (curr_card->dbase &&
- !curr_card->dbase->rdonly &&
- curr_card->dbase->modified &&
- !curr_card->form->rdonly &&
- !write_dbase(curr_card->dbase,
- curr_card->form, FALSE))
- return;
- create_formedit_window(curr_card->form, FALSE, FALSE);
- } else
- create_error_popup(toplevel, 0,
- "Please choose database to edit\nfrom Database pulldown");
- break;
-
- case 1: /* new */
- switch_form(0);
- create_formedit_window(0, FALSE, TRUE);
- break;
-
- case 2: /* clone */
- if (curr_card && curr_card->form) {
- if (curr_card->dbase &&
- !curr_card->dbase->rdonly &&
- curr_card->dbase->modified &&
- !curr_card->form->rdonly &&
- !write_dbase(curr_card->dbase,
- curr_card->form, FALSE))
- return;
- create_formedit_window(curr_card->form, TRUE, TRUE);
- } else
- create_error_popup(toplevel, 0,
- "Please choose database from Database pulldown first");
- break;
- }
- }
-
-
- /*ARGSUSED*/
- static void help_pulldown(
- Widget widget,
- int item,
- XmToggleButtonCallbackStruct *data)
- {
- Cursor cursor;
- Widget w;
-
- switch (item) {
- case 0: /* context */
- cursor = XCreateFontCursor(display, XC_question_arrow);
- if (w = XmTrackingLocate(mainwindow, cursor, False)) {
- data->reason = XmCR_HELP;
- XtCallCallbacks(w, XmNhelpCallback, &data);
- }
- XFreeCursor(display, cursor);
- break;
-
- case 1: /* database */
- create_dbase_info_popup(curr_card);
- break;
-
- case 2: /* intro */
- help_callback(mainwindow, "intro");
- break;
-
- case 3: /* help */
- help_callback(mainwindow, "help");
- break;
-
- case 4: /* trouble */
- help_callback(mainwindow, "trouble");
- break;
-
- case 5: /* files */
- help_callback(mainwindow, "files");
- break;
-
- case 6: /* expr */
- help_callback(mainwindow, "grammar");
- break;
-
- case 7: /* resources */
- help_callback(mainwindow, "resources");
- break;
- }
- }
-
-
- /*ARGSUSED*/
- static void dbase_pulldown(
- Widget widget,
- int item,
- XmToggleButtonCallbackStruct *data)
- {
- char path[1024];
-
- card_readback_texts(curr_card, -1);
- sprintf(path, "%s/%s.gf", dbpath[item], dbname[item]);
- switch_form(path);
- remake_dbase_pulldown();
- }
-
-
- /*ARGSUSED*/
- static void section_pulldown(
- Widget widget,
- int item,
- XmToggleButtonCallbackStruct *data)
- {
- card_readback_texts(curr_card, -1);
- if (item == curr_card->dbase->nsects+1 || item == MAXSC-1 ||
- !curr_card->dbase->havesects)
- create_newsect_popup();
- else {
- curr_card->dbase->currsect = item-1;
- query_all(curr_card);
- create_summary_menu(curr_card, w_summary, mainwindow);
-
- curr_card->row = curr_card->query ? curr_card->query[0]
- : curr_card->dbase->nrows;
- fillout_card(curr_card, FALSE);
- }
- }
-
-
- /*ARGSUSED*/
- static void query_pulldown(
- Widget widget,
- int item,
- XmToggleButtonCallbackStruct *data)
- {
- print_info_line();
- if (!curr_card || !curr_card->dbase || !curr_card->dbase->nrows)
- return;
- card_readback_texts(curr_card, -1);
- if (item == 0)
- query_all(curr_card);
-
- else if (*curr_card->form->query[item-1].query == '/') {
- char *query = curr_card->form->query[item-1].query;
- char *string = XtMalloc(strlen(query));
- strcpy(string, query+1);
- append_search_string(string);
- query_search(curr_card, query+1);
- } else {
- char *query = curr_card->form->query[item-1].query;
- if (pref.query2search) {
- char *string = XtMalloc(strlen(query)+1);
- strcpy(string, query);
- append_search_string(string);
- }
- query_eval(curr_card, query);
- }
- create_summary_menu(curr_card, w_summary, mainwindow);
-
- curr_card->row = curr_card->query ? curr_card->query[0]
- : curr_card->dbase->nrows;
- fillout_card(curr_card, FALSE);
- }
-
-
- /*ARGSUSED*/
- static void sort_pulldown(
- Widget widget,
- int item,
- XmToggleButtonCallbackStruct *data)
- {
- card_readback_texts(curr_card, -1);
- dbase_sort(curr_card, item);
- create_summary_menu(curr_card, w_summary, mainwindow);
- curr_card->row = curr_card->query ? curr_card->query[0]
- : curr_card->dbase->nrows;
- fillout_card(curr_card, FALSE);
- }
-
-
- /*
- * search for a search string, or for matching expressions. Put matching
- * cards into the summary. The string is an expression if it begins with
- * '(' or '{', or a search string otherwise. This is called from the
- * switch statement in expressions too.
- */
-
- /*ARGSUSED*/
- void search_cards(
- CARD *card,
- char *string)
- {
- if (!string || !*string)
- return;
- print_info_line();
- card_readback_texts(card, -1);
- if (!card || !card->dbase || !card->dbase->nrows)
- return;
- query_any(card, string);
- create_summary_menu(card, w_summary, mainwindow);
- card->row = card->query ? card->query[0] : card->dbase->nrows;
- fillout_card(card, FALSE);
- }
-
-
- /*
- * Searches. When a search string is entered, read it from the button and
- * search for it. The arrows put a string from the history array into the
- * button, where it can be searched for. The query pulldown can append a
- * string to the history if pref.query2search is on.
- */
-
- static char *history[NHIST];
- static int s_curr, s_offs;
-
- /*ARGSUSED*/
- static void search_callback(
- Widget widget,
- int inc,
- XmToggleButtonCallbackStruct *data)
- {
- if (inc) {
- int o = s_offs + inc;
- if (o > -NHIST && o <= 0 && history[(s_curr + o) % NHIST]) {
- s_offs = o;
- print_text_button_s(w_search,
- history[(s_curr + o + NHIST) % NHIST]);
- }
- append_search_string(0);
- } else {
- char *string = XmTextGetString(w_search);
- search_cards(curr_card, string);
- append_search_string(string);
- }
- }
-
- static void append_search_string(
- char *text)
- {
- Arg arg;
-
- if (text) {
- print_text_button_s(w_search, text);
- s_offs = 0;
- if (history[s_curr] && *history[s_curr]
- && strcmp(history[s_curr], text))
- s_curr = (s_curr + 1) % NHIST;
- if (history[s_curr])
- XtFree(history[s_curr]);
- history[s_curr] = text;
- }
- XtSetArg(arg, XmNsensitive, s_offs < 0);
- XtSetValues(w_next, &arg, 1);
- XtSetArg(arg, XmNsensitive, s_offs > -NHIST+1 &&
- history[(s_curr + s_offs + NHIST -1) % NHIST]);
- XtSetValues(w_prev, &arg, 1);
- }
-
-
- /*
- * One of the letter buttons (a..z, misc, all) was pressed. Do the appropriate
- * search and display the result in the summary.
- */
-
- /*ARGSUSED*/
- static void letter_callback(
- Widget widget,
- int letter,
- XmToggleButtonCallbackStruct *cbs)
- {
- if (!curr_card || !curr_card->dbase || !curr_card->dbase->nrows)
- return;
- card_readback_texts(curr_card, -1);
- query_letter(curr_card, letter);
- create_summary_menu(curr_card, w_summary, mainwindow);
- curr_card->row = curr_card->query ? curr_card->query[0]
- : curr_card->dbase->nrows;
- fillout_card(curr_card, FALSE);
- }
-
-
- /*
- * go forward or backward in the summary list if there is one. If there is
- * no summary, we must be adding cards and the user wants to see previously
- * added cards; step in the raw database in this case.
- */
-
- /*ARGSUSED*/
- static void pos_callback(
- Widget widget,
- int inc,
- XmToggleButtonCallbackStruct *data)
- {
- register CARD *card = curr_card;
-
- card_readback_texts(curr_card, -1);
- if (card->qcurr + inc >= 0 &&
- card->qcurr + inc < card->nquery) {
- card->qcurr += inc;
- card->row = card->query[card->qcurr];
- fillout_card(card, FALSE);
- scroll_summary(card);
-
- } else if (card->nquery == 0 && card->row + inc >= 0
- && card->row + inc < card->dbase->nrows){
- card->row += inc;
- fillout_card(card, FALSE);
- }
- }
-
-
- /*
- * add a new card to the database. Since we don't know whether the new card
- * will be part of the summary when it is finished, remove the summary first.
- * When finished, find the first text input item and put the cursor into it.
- */
-
- /*ARGSUSED*/
- static void add_card(
- BOOL dup)
- {
- register CARD *card = curr_card;
- register ITEM *item;
- register DBASE *dbase = card->dbase;
- int i, s;
- int oldrow = card->row;
-
- if (dbase->nsects > 1 && dbase->currsect < 0) {
- create_error_popup(toplevel, 0,
- "Choose a section from the section pulldown first");
- return;
- }
- card_readback_texts(card, -1);
- s = dbase->nsects > 1 ? dbase->currsect : 0;
- if (dbase->sect[s].rdonly) {
- create_error_popup(toplevel, 0,
- "Section file\n\"%s\" is read-only",
- dbase->sect[s].path);
- return;
- }
- if (!dbase_addrow(&card->row, dbase)) {
- create_error_popup(toplevel, errno,
- "No memory for new database row");
- return;
- }
- if (dup)
- for (i=0; i < dbase->maxcolumns; i++)
- dbase_put(dbase, card->row, i,
- mystrdup(dbase_get(dbase, oldrow, i)));
- else
- for (i=0; i < card->form->nitems; i++, item++) {
- item = card->form->items[i];
- if (IN_DBASE(item->type) && item->idefault)
- dbase_put(dbase, card->row, item->column,
- mystrdup(evaluate(card, item->idefault)));
- }
- query_none(card);
- create_summary_menu(card, w_summary, mainwindow);
- fillout_card(card, FALSE);
- scroll_summary(card);
- for (i=0; i < card->form->nitems; i++, item++) {
- item = card->form->items[i];
- if (item->type == IT_INPUT || item->type == IT_TIME
- || item->type == IT_NOTE) {
- XmProcessTraversal(card->items[i].w0,
- XmTRAVERSE_CURRENT);
- break;
- }
- }
- }
-
-
- /*ARGSUSED*/
- static void new_callback(
- Widget widget,
- XtPointer null,
- XmToggleButtonCallbackStruct *cbs)
- {
- add_card(FALSE);
- }
-
-
- /*
- * duplicate a card. This does the same as New, but fills the card with
- * the same data as the current card.
- */
-
- /*ARGSUSED*/
- static void dup_callback(
- Widget widget,
- XtPointer null,
- XmToggleButtonCallbackStruct *cbs)
- {
- if (curr_card->row >= 0)
- add_card(TRUE);
- }
-
-
- /*
- * delete a card. Since the summary should not be deleted, the deleted card
- * must be removed from the query[] list. Since the query list contains the
- * row numbers of the cards it lists, and rows may get renumbered if one is
- * removed, row indices > deleted row must be decremented.
- */
-
- /*ARGSUSED*/
- static void del_callback(
- Widget widget,
- XtPointer null,
- XmToggleButtonCallbackStruct *data)
- {
- register CARD *card = curr_card;
- register int *p, *q;
- int i, s;
-
- if (card->dbase->nrows == 0 || card->row >= card->dbase->nrows)
- return;
- s = card->dbase->row[card->row]->section;
- if (card->dbase->sect[s].rdonly) {
- create_error_popup(toplevel, 0,
- "section file\n\"%s\" is read-only",
- card->dbase->sect[s].path);
- return;
- }
- dbase_delrow(card->row, card->dbase);
- if (card->row >= card->dbase->nrows)
- card->row = card->dbase->nrows - 1;
- p = q = &card->query[0];
- for (i=0; i < card->nquery; i++, p++) {
- *q = *p - (*p > card->row);
- q += *p != card->row;
- }
- card->nquery -= p - q;
- print_info_line();
- fillout_card(card, FALSE);
- create_summary_menu(card, w_summary, mainwindow);
- }
-
-
- /*
- * assign new section to the current card (called from the option popup)
- */
-
- /*ARGSUSED*/
- static void sect_callback(
- Widget widget,
- int item,
- XmToggleButtonCallbackStruct *data)
- {
- register CARD *card = curr_card;
- register SECTION *sect = card->dbase->sect;
- int old, new;
-
- old = card->dbase->row[card->row]->section;
- new = item;
- if (sect[old].rdonly)
- create_error_popup(toplevel, 0,
- "section file\n\"%s\" is read-only", sect[old].path);
- else if (sect[new].rdonly)
- create_error_popup(toplevel, 0,
- "section file\n\"%s\" is read-only", sect[new].path);
- else {
- sect[old].nrows--;
- sect[new].nrows++;
- sect[old].modified = TRUE;
- sect[new].modified = TRUE;
- card->dbase->row[card->row]->section = new;
- card->dbase->modified = TRUE;
- print_info_line();
- }
- remake_section_popup(FALSE);
- }
-